package matrixMultiplicationAnalysis.matrixMultipleImpl;

import matrixMultiplicationAnalysis.Cache.CacheSimulator;
import matrixMultiplicationAnalysis.Matrix.matrix;
import matrixMultiplicationAnalysis.Matrix.matrixMultiple;

public class matrixMultipleJKI implements matrixMultiple{
    public int cacheSize, blockSize;
    private String experimentName;

    public matrixMultipleJKI(int cacheSize, int blockSize){
        this(cacheSize, blockSize, "JKI_Experiment");
    }
    
    public matrixMultipleJKI(int cacheSize, int blockSize, String experimentName){
        this.cacheSize = cacheSize;
        this.blockSize = blockSize;
        this.experimentName = experimentName;
    }
    @Override
    public matrix multipleMatrix(matrix a, matrix b){
        if(a.column != b.row){
            System.out.println("矩阵乘法的矩阵行列不匹配");
            return new matrix();
        }
        
        // 为每个矩阵创建缓存模拟器，明确指定矩阵类型
        CacheSimulator cacheSimulatorA = new CacheSimulator(cacheSize, blockSize, a.column, 
                                                          experimentName, "A");
        CacheSimulator cacheSimulatorB = new CacheSimulator(cacheSize, blockSize, b.column, 
                                                          experimentName, "B");
        CacheSimulator cacheSimulatorC = new CacheSimulator(cacheSize, blockSize, b.column, 
                                                          experimentName, "C");

        int row = a.row, column = b.column, middle = a.column;
        matrix ans = new matrix(row, column);
        
        System.out.println("开始执行矩阵乘法: " + experimentName);
        
        for(int j = 0; j < column; j++){
            for(int k = 0; k < middle; k++){
                for(int i = 0; i < row; i++){
                    ans.mat[i][j] += a.at(i, k) * b.at(k, j);
                    cacheSimulatorA.accessMatrixElement(i, k);
                    cacheSimulatorB.accessMatrixElement(k, j);
                    cacheSimulatorC.accessMatrixElement(i, j);
                }
            }
        }
        
        // 输出统计信息
        System.out.println("===矩阵A的缓存统计数据===");
        cacheSimulatorA.printStatistics();

        System.out.println("===矩阵B的缓存统计数据===");
        cacheSimulatorB.printStatistics();

        System.out.println("===矩阵C的缓存统计数据===");
        cacheSimulatorC.printStatistics();

        // 计算总统计
        int[] statsA = cacheSimulatorA.getStatus();
        int[] statsB = cacheSimulatorB.getStatus();
        int[] statsC = cacheSimulatorC.getStatus();
        
        int totalHits = statsA[0] + statsB[0] + statsC[0];
        int totalMisses = statsA[1] + statsB[1] + statsC[1];
        int totalEvictions = statsA[2] + statsB[2] + statsC[2];

        System.out.println("===总统计数据===");
        int totalAccesses = totalHits + totalMisses;
        System.out.println("总访问次数: " + totalAccesses);
        System.out.println("命中次数: " + totalHits);
        System.out.println("缺失次数: " + totalMisses);
        System.out.println("替换次数: " + totalEvictions);
        System.out.println("命中率: " + String.format("%.2f%%", (double)totalHits / totalAccesses * 100));

        // 将结果写入CSV文件
        cacheSimulatorA.writeResultsToCSV("jki", a.row);
        cacheSimulatorB.writeResultsToCSV("jki", a.row);
        cacheSimulatorC.writeResultsToCSV("jki", a.row);

        return ans;
    }
}
